home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / msysjour / vol06 / 03 / winedd / logger.c < prev    next >
Text File  |  1991-05-01  |  15KB  |  466 lines

  1. /* ----------------------------- LOGGER.C ----------------------------------
  2.                      Embedded Device Driver Application.
  3.                               Application module.
  4.  
  5.                            Spark Software Inc. 1991.
  6.    ------------------------------------------------------------------------- */
  7.  
  8. /* The following is an intentionally empty definition; this is used to tell */
  9. /* the compiler that we wish to have the global variables in "globals.h"    */
  10. /* declared in this source module and only defined in all others.           */
  11. #define PUBLIC
  12.  
  13. #include <windows.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include "device.h"
  17. #include "logmsg.h"
  18. #include "defs.h"
  19.  
  20. /* Macro definitions. */
  21. #define ShowRegisters( )                                            \
  22.     sprintf( szString ,                                             \
  23.         "%04X  %04X  %04X  %04X  "                                  \
  24.         "%04X:%04X   %04X:%04X   "                                  \
  25.         "%04X:%04X   %04X  %04X" ,                                  \
  26.         Registers.ax , Registers.bx , Registers.cx , Registers.dx , \
  27.         Registers.cs , Registers.ip , Registers.ds , Registers.si , \
  28.         Registers.es , Registers.di , Registers.bp , Registers.sp );\
  29.     TextOut( hDC , 0 , nY , szString , strlen( szString ) );
  30.  
  31.  
  32. /* Public function prototypes. */
  33. PUBLIC int      PASCAL WinMain( HANDLE , HANDLE , LPSTR , int );
  34. PUBLIC LONG FAR PASCAL AppWndProc( HWND , WORD , WORD , LONG );
  35.  
  36. /* Private function prototypes. */
  37. PRIVATE VOID  NEAR PASCAL GetNewData( HWND , WORD );
  38. PRIVATE BOOL  NEAR PASCAL Init( HANDLE );
  39. PRIVATE LPSTR NEAR PASCAL FormatDevErrorMsg( WORD , WORD );
  40. PRIVATE LONG  NEAR PASCAL DoClose( HWND );
  41. PRIVATE LONG  NEAR PASCAL DoCreate( HWND );
  42. PRIVATE LONG  NEAR PASCAL DoDestroy( HWND );
  43. PRIVATE LONG  NEAR PASCAL DoPaint( HWND );
  44. PRIVATE LONG  NEAR PASCAL DoSize( HWND , WORD );
  45.  
  46. /* Private data object declarations. */
  47. PRIVATE BOOL  bDisplayed;               /* Displayed >= 1 set of registers?   */
  48. PRIVATE BOOL  bOpened;                  /* Was the pseudodevice opened?       */
  49. PRIVATE BOOL  bError;                   /* Did we get a read error?           */
  50. PRIVATE BYTE  szAppName[ ] = APP_NAME;  /* Application name.                  */
  51. PRIVATE BYTE  szClass[ ] = APP_CLASS;   /* Window class name.                 */
  52. PRIVATE BYTE  szColumnHeadings[ ] = COLUMN_HEADINGS;    /* Obv.               */
  53. PRIVATE BYTE      szString[ 81 ];       /* Generic text buffer.               */
  54. PRIVATE WORD      wCharWidth , wCharHeight;     /* Font information.          */
  55. PRIVATE WORD      wLoggerDefunctMsg;    /* For message sent when we stop.     */
  56. PRIVATE HANDLE    hInst , hPrevInst;    /* Handles to program instances.      */
  57. PRIVATE HWND      hWndMaster;           /* Handle of our master window.       */
  58. PRIVATE REGISTERS Registers;            /* Buffer for machine registers.      */
  59.  
  60.  
  61. PUBLIC int PASCAL WinMain( hInstance , hPrevInstance , lpszCmdLine , nCmdShow )
  62. HANDLE hInstance , hPrevInstance;
  63. LPSTR  lpszCmdLine;
  64. int    nCmdShow;
  65. {
  66.     WORD wItems , wExecReturn;
  67.     MSG  Msg;
  68.  
  69.  
  70.     /* Call initialization procedure if this is the first instance. */
  71.     if( !hPrevInstance && !Init( hInstance ) )
  72.         return 0;
  73.  
  74.     if( hPrevInstance )
  75.     {
  76.         /* See if the top-level window of this app still exists. */
  77.         GetInstanceData( hPrevInstance , (PSTR)&hWndMaster , sizeof hWndMaster );
  78.  
  79.         if( IsWindow( hWndMaster ) )
  80.         {
  81.             /* We won't allow more than one invocation of this program. */
  82.             sprintf( szString , "%s already active." , APP_NAME );
  83.             MessageBox( GetFocus( ) , (LPSTR)szString , (LPSTR)szAppName , MB_OK | MB_ICONHAND );
  84.             return 0;
  85.         }
  86.     }
  87.  
  88.     /* Create our top-level (i.e., master) window. */
  89.     hWndMaster = CreateWindow(
  90.           (LPSTR)szClass                        ,
  91.           (LPSTR)szAppName                      ,
  92.           WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN ,
  93.           CW_USEDEFAULT                         ,
  94.           0                                     ,
  95.           CW_USEDEFAULT                         ,
  96.           0                                     ,
  97.           (HWND)NULL                            ,
  98.           (HMENU)NULL                           ,
  99.           hInstance                             ,
  100.           (LPSTR)NULL
  101.         );
  102.  
  103.     hInst     = hInstance;
  104.     hPrevInst = hPrevInstance;
  105.  
  106.     /* Start up the feeder (device simulator). */
  107.     if( ( wExecReturn = WinExec( FEEDER_APP_NAME , SW_SHOWMINIMIZED ) ) <= 32 )
  108.     {
  109.         sprintf( szString , "Cannot execute %s; error %u" , FEEDER_APP_NAME , wExecReturn );
  110.         MessageBox( GetFocus( ) , (LPSTR)szString , (LPSTR)szAppName , MB_OK | MB_ICONHAND );
  111.     }
  112.  
  113.     /* Show the window and send keyboard input to it. */
  114.     ShowWindow( hWndMaster , nCmdShow );
  115.     SetFocus( hWndMaster );
  116.  
  117.     /* Process messages from our queue. */
  118.     while( TRUE )
  119.     {
  120.         if( PeekMessage( (LPMSG)&Msg , NULL , 0 , 0 , PM_REMOVE ) )
  121.         {
  122.             if( Msg.message == WM_QUIT )
  123.             {
  124.                 return (int)Msg.wParam;
  125.             }
  126.  
  127.             TranslateMessage( (LPMSG)&Msg );
  128.             DispatchMessage(  (LPMSG)&Msg );
  129.         }
  130.  
  131.         /* If there are one or more unread items in the interrupt buffer... */
  132.         /* NOTE: working in this part of the message loop allows */
  133.         /* us to process input when we have 0 or more messages.  */
  134.         if( bOpened && !bError && ( wItems = GetNumUnreadItems( hWndMaster ) ) )
  135.         {
  136.             /* Process the unread data NOW. */
  137.             GetNewData( hWndMaster , wItems );
  138.         }
  139.     }
  140.  
  141. }/* WinMain( ) */
  142.  
  143.  
  144. /* Procedure called when the application is loaded for the first time */
  145. PRIVATE BOOL NEAR PASCAL Init( hInstance )
  146. HANDLE hInstance;
  147. {
  148.     WNDCLASS Class;
  149.  
  150.  
  151.     /* Register the window class. */
  152.     Class.hCursor       = LoadCursor( NULL, IDC_ARROW );
  153.     Class.hIcon         = LoadIcon( hInstance , MAKEINTRESOURCE( APPICON ) );
  154.     Class.lpszMenuName  = (LPSTR)NULL;
  155.     Class.lpszClassName = (LPSTR)szClass;
  156.     Class.hbrBackground = GetStockObject( WHITE_BRUSH );
  157.     Class.hInstance     = hInstance;
  158.     Class.style         = CS_HREDRAW | CS_VREDRAW;
  159.     Class.lpfnWndProc   = AppWndProc;
  160.     Class.cbClsExtra    = 0;
  161.     Class.cbWndExtra    = 0;
  162.  
  163.     if( !RegisterClass( (LPWNDCLASS)&Class ) )
  164.         /* Initialization failed. */
  165.         return FALSE;
  166.  
  167.     return TRUE;
  168.  
  169. }/* Init( ) */
  170.  
  171.  
  172. PUBLIC LONG FAR PASCAL AppWndProc( hWnd , wMessage , wParam , lParam )
  173. HWND hWnd;
  174. WORD wMessage;
  175. WORD wParam;
  176. LONG lParam;
  177. {
  178.     switch( wMessage )
  179.     {
  180.     case WM_CREATE:
  181.         return DoCreate( hWnd );
  182.  
  183.     case WM_CLOSE:
  184.         return DoClose( hWnd );
  185.  
  186.     case WM_DESTROY:
  187.         return DoDestroy( hWnd );
  188.  
  189.     case WM_SIZE:
  190.         return DoSize( hWnd , wParam );
  191.  
  192.     case WM_PAINT:
  193.         return DoPaint( hWnd );
  194.     }
  195.  
  196.     return DefWindowProc( hWnd , wMessage , wParam , lParam );
  197.  
  198. }/* AppWndProc( ) */
  199.  
  200.  
  201. /* Create and/or access all resources to be used in this application. */
  202. PRIVATE LONG NEAR PASCAL DoCreate( hWnd )
  203. HWND hWnd;
  204. {
  205.     HFONT      hOldFont;
  206.     HDC        hDC;
  207.     TEXTMETRIC tmInfo;
  208.  
  209.  
  210.     /* Get some info. about our font and screen. */
  211.     hDC = GetDC( hWnd );
  212.     hOldFont = SelectObject( hDC , GetStockObject( SYSTEM_FIXED_FONT ) );
  213.     GetTextMetrics( hDC , (LPTEXTMETRIC)&tmInfo );
  214.     SelectObject( hDC , hOldFont );
  215.     ReleaseDC( hWnd , hDC );
  216.     wCharWidth  = tmInfo.tmAveCharWidth;
  217.     wCharHeight = tmInfo.tmHeight + tmInfo.tmExternalLeading;
  218.  
  219.     /* Open the device. */
  220.     bOpened = DevOpen( hWnd );
  221.  
  222.     /* Register a message index to be sent when we are about to stop. */
  223.     wLoggerDefunctMsg = RegisterWindowMessage( LOGGER_DEFUNCT_MSG );
  224.     return (LONG)1;
  225.  
  226.     return (LONG)1;
  227.  
  228. }/* DoCreate( ) */
  229.  
  230.  
  231. PRIVATE LONG NEAR PASCAL DoClose( hWnd )
  232. HWND hWnd;
  233. {
  234.     /* LOGGER is terminating; tell FEEDER. */
  235.     SendMessage( (HWND)-1 , wLoggerDefunctMsg , 0 , (LONG)0 );
  236.     DestroyWindow( hWnd );
  237.     return (LONG)1;
  238.  
  239. }/* DoClose( ) */
  240.  
  241.  
  242. /* Destroy and/or relinquish all resources used in this application. */
  243. PRIVATE LONG NEAR PASCAL DoDestroy( hWnd )
  244. HWND hWnd;
  245. {
  246.     /* Close the pseudodevice. */
  247.     DevClose( hWnd );
  248.     bOpened = FALSE;
  249.  
  250.     /* Finish up. */
  251.     PostQuitMessage( 0 );
  252.     return (LONG)1;
  253.  
  254. }/* DoDestroy( ) */
  255.  
  256.  
  257. PRIVATE LONG NEAR PASCAL DoSize( hWnd , wParam )
  258. HWND hWnd;
  259. WORD wParam;
  260. {
  261.     HDC   hDC;
  262.     HFONT hOldFont;
  263.     RECT  rInfo;
  264.  
  265.  
  266.     if( wParam == SIZENORMAL )
  267.     {
  268.         /* Size the window according to its text. */
  269.         hDC = GetDC( hWnd );
  270.         hOldFont = SelectObject( hDC , GetStockObject( SYSTEM_FIXED_FONT ) );
  271.  
  272.         GetClientRect( hWnd , (LPRECT)&rInfo );
  273.         rInfo.bottom = rInfo.top + wCharHeight * 2;
  274.         rInfo.right = rInfo.left + wCharWidth * 72;
  275.         AdjustWindowRect( (LPRECT)&rInfo , GetWindowLong( hWnd , GWL_STYLE ) , FALSE );
  276.         SetWindowPos( hWnd , (HWND)NULL , 0 , 0 , rInfo.right - rInfo.left , rInfo.bottom - rInfo.top , SWP_NOMOVE | SWP_NOZORDER );
  277.  
  278.         SelectObject( hDC , hOldFont );
  279.         ReleaseDC( hWnd , hDC );
  280.     }
  281.     return (LONG)1;
  282.  
  283. }/* DoSize( ) */
  284.  
  285.  
  286. PRIVATE LONG NEAR PASCAL DoPaint( hWnd )
  287. HWND hWnd;
  288. {
  289.     register int nY;
  290.     HFONT        hOldFont;
  291.     HDC          hDC;
  292.     PAINTSTRUCT  psInfo;
  293.  
  294.  
  295.     /* Resize the window. */
  296.     /* Select a monospace font. */
  297.     hDC = BeginPaint( hWnd , (LPPAINTSTRUCT)&psInfo );
  298.     hOldFont = SelectObject( hDC , GetStockObject( SYSTEM_FIXED_FONT ) );
  299.  
  300.     /* Was the window erased? */
  301.     if( !psInfo.fErase )
  302.     {
  303.         /* Window was not erased.  Since we're only showing the   */
  304.         /* last item gotten from the driver (and several items    */
  305.         /* may have been displayed previously), erase the window. */
  306.         SendMessage( hWnd , WM_ERASEBKGND , (WORD)hDC , (LONG)0 );
  307.     }
  308.  
  309.     /* Start at the first line of text in the window. */
  310.     nY = 0;
  311.     TextOut( hDC , 0 , nY , szColumnHeadings , strlen( szColumnHeadings ) );
  312.  
  313.     /* If we displayed at least one set of registers... */
  314.     if( bDisplayed )
  315.     {
  316.         /* ...Display the register contents for the last interrupt. */
  317.         nY += wCharHeight;
  318.         ShowRegisters( );
  319.     }
  320.  
  321.     SelectObject( hDC , hOldFont );
  322.     EndPaint( hWnd , (LPPAINTSTRUCT)&psInfo );
  323.     return (LONG)1;
  324.  
  325. }/* DoPaint( ) */
  326.  
  327.  
  328. PRIVATE VOID NEAR PASCAL GetNewData( hWnd , wItems )
  329. HWND hWnd;
  330. WORD wItems;
  331. {
  332.     WORD         wDevError , wNumErrors;
  333.     register int nY;
  334.     HFONT        hOldFont;
  335.     HDC          hDC;
  336.  
  337.  
  338.     hDC = GetDC( hWnd );
  339.     hOldFont = SelectObject( hDC , GetStockObject( SYSTEM_FIXED_FONT ) );
  340.  
  341.     /* Read the data from the pseudodevice's buffer. */
  342.     for(
  343.         nY = 0;
  344.         wItems && DevRead( hWnd , (LPREGISTERS)&Registers , 1 );
  345.         nY += wCharHeight , wItems--
  346.        )
  347.     {
  348.         if( !nY )
  349.         {
  350.             /* Erase the window upon reading the first item. */
  351.             SendMessage( hWnd , WM_ERASEBKGND , (WORD)hDC , (LONG)0 );
  352.  
  353.             /* Display the column headings. */
  354.             TextOut( hDC , 0 , nY , szColumnHeadings , strlen( szColumnHeadings ) );
  355.             nY += wCharHeight;
  356.         }
  357.  
  358.         /* Check for a device error on this read. */
  359.         if( ( wNumErrors = GetDevError( hWnd , (LPWORD)&wDevError , TRUE ) ) )
  360.         {
  361.             bError = TRUE;
  362.             Registers.ax = Registers.bx = Registers.cx = Registers.dx =
  363.             Registers.cs = Registers.ds = Registers.es = Registers.si =
  364.             Registers.di = Registers.bp = Registers.sp = Registers.ip =
  365.             Registers.flags = 0;
  366.             MessageBox( GetFocus( ) , FormatDevErrorMsg( wDevError , wNumErrors ) , (LPSTR)szAppName , MB_OK | MB_ICONHAND );
  367.         }
  368.         else
  369.         {
  370.  
  371.             /* Display the register contents for all interrupts */
  372.             /* that occurred since the last read.               */
  373.             ShowRegisters( );
  374.         }
  375.     }
  376.  
  377.     /* Check for a device error on the last read if DevRead( ) returned 0. */
  378.     if( ( wNumErrors = GetDevError( hWnd , (LPWORD)&wDevError , TRUE ) ) )
  379.     {
  380.         bError = TRUE;
  381.         MessageBox( GetFocus( ) , FormatDevErrorMsg( wDevError , wNumErrors ) , (LPSTR)szAppName , MB_OK | MB_ICONHAND );
  382.     }
  383.  
  384.     SelectObject( hDC , hOldFont );
  385.     ReleaseDC( hWnd , hDC );
  386.  
  387.     /* Say that we displayed at least one set of registers. */
  388.     bDisplayed = TRUE;
  389.  
  390. }/* GetNewData( ) */
  391.  
  392.  
  393. PRIVATE LPSTR NEAR PASCAL FormatDevErrorMsg( wDevError , wNumErrors )
  394. WORD wDevError;
  395. WORD wNumErrors;
  396. {
  397.     BOOL          bMemory;
  398.     register WORD wIndex;
  399.     WORD          wErrors;
  400.  
  401.  
  402.     wIndex = wErrors = 0;
  403.     *szString = '\0';
  404.     bMemory = FALSE;
  405.  
  406.     /* Build an error message. */
  407.     if( wDevError )
  408.     {
  409.         do
  410.         {
  411.             if( !wIndex )
  412.             {
  413.                 wIndex = 1;
  414.             }
  415.             else
  416.             {
  417.                 wIndex <<= 1;
  418.             }
  419.  
  420.             switch( wIndex & wDevError )
  421.             {
  422.             case DEVERROR_OVERRUN:
  423.                 if( wErrors )
  424.                 {
  425.                     strcat( szString , "; " );
  426.                 }
  427.  
  428.                 strcat( szString , "Buffer overrun error" );
  429.                 wErrors++;
  430.                 break;
  431.  
  432.             case DEVERROR_INTERNAL:
  433.                 if( wErrors )
  434.                 {
  435.                     strcat( szString , "; " );
  436.                 }
  437.  
  438.                 strcat( szString , "Internal error" );
  439.                 wErrors++;
  440.                 break;
  441.  
  442.             case DEVERROR_NOTOWNER:
  443.                 if( wErrors )
  444.                 {
  445.                     strcat( szString , "; " );
  446.                 }
  447.  
  448.                 strcat( szString , "Device not owned by this window error" );
  449.                 wErrors++;
  450.                 break;
  451.             }
  452.         }
  453.         while( wIndex != HIGHEST_DEVERROR );
  454.         sprintf( szString + strlen( szString ) , " (%u errors in all)." , wNumErrors );
  455.     }
  456.     else
  457.     {
  458.         strcpy( szString , "No errors." );
  459.     }
  460.  
  461.     return (LPSTR)szString;
  462.  
  463. }/* FormatDevErrorMsg( ) */
  464.  
  465. /* EOF */
  466.